const fs = require("fs-extra");
const path = require("path");
const chalk = require("chalk");
const chokidar = require("chokidar");
const glob = require("glob");
const yaml = require("js-yaml");
const config = require("./config.cjs");

class PagesGenerator {
    constructor(options = {}) {
        this.options = { ...config, ...options };
        this.cache = new Map();
    }

    async run() {
        try {
            console.log(chalk.blue("Start generating pages.json..."));
            await this.generate();
            console.log(chalk.green("pages.json generating success!"));

            if (process.argv.includes("--watch")) {
                this.startWatcher();
            }
        } catch (error) {
            console.error(chalk.red("generating fail:"), error);
            process.exit(1);
        }
    }

    async generate() {
        const pages = await this.scanPages(this.options.dirs.main);
        const subPackages = await this.scanSubPackages();

        const output = {
            pages,
            globalStyle: this.options.globalStyle,
            ...(subPackages.length > 0 && { subPackages }),
            ...this.options.mixins
        };

        await fs.writeJson(this.options.dirs.output, output, { spaces: 2 });
    }

    sortWithIndexFirst(files) {
        return [...files].sort((a, b) => {
            if (a === "index/index.vue") return -1; // a 是 index/index.vue，排前面
            if (b === "index/index.vue") return 1; // b 是 index/index.vue，a 排后面
            return files.indexOf(a) - files.indexOf(b); // 保持其他顺序不变
        });
    }

    async scanPages(dir) {
        const fullDir = path.join(this.options.rootDir, dir);
        if (!fs.existsSync(fullDir)) return [];

        const pageDirs = glob.sync("**/*.vue", { cwd: fullDir, ignore: ["**/components/**"] });
        const pages = [];

        for (const pageDir of this.sortWithIndexFirst(pageDirs)) {
            const pagePath = pageDir.replace(/\.vue$/, "");
            const pageName = pageDir.replace("/", "-").replace(/\.vue$/, "");

            let configPath = `${dir}/${pagePath}`.replace("src/", "").split("/");

            configPath.pop();

            pages.push({
                path: `${dir}/${pagePath}`.replace("src/", ""),
                style: {
                    ...this.options.defaultPageStyle,
                    navigationBarTitleText: this.formatTitle(pageName),
                    ...(await this.getPageConfig(configPath.join("/")))
                }
            });
        }

        return pages;
    }

    async scanSubPackages() {
        const fullDir = path.join(this.options.rootDir, this.options.dirs.sub);
        if (!fs.existsSync(fullDir)) return [];

        const packageDirs = glob.sync("*/", { cwd: fullDir });
        const subPackages = [];

        for (const pkgDir of packageDirs) {
            const pkgName = pkgDir.replace("/", "");
            const pkgPath = path.join(fullDir, pkgDir);

            const pages = await this.scanPages(path.join(this.options.dirs.sub, pkgDir));

            const root = `${this.options.dirs.sub}/${pkgName}`.replace("src/", "");

            subPackages.push({
                root,
                pages: pages.map((p) => ({
                    ...p,
                    path: p.path.replace(`${root}/`, "")
                }))
            });
        }

        return subPackages;
    }

    async getPageConfig(pagePath) {
        // 尝试读取多种格式的配置文件
        const configFiles = ["page.config.json", "page.config.yaml", "page.config.yml"];

        for (const file of configFiles) {
            const configPath = path.join(this.options.rootDir, `/src/${pagePath}`, file);

            if (fs.existsSync(configPath)) {
                const content = await fs.readFile(configPath, "utf8");

                if (file.endsWith(".json")) {
                    return JSON.parse(content);
                } else {
                    return yaml.load(content);
                }
            }
        }

        return {};
    }

    formatTitle(str) {
        return str
            .split("-")
            .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
            .join(" ");
    }

    startWatcher() {
        console.log(chalk.yellow("进入监听模式..."));

        const watchPaths = [
            path.join(this.options.rootDir, this.options.dirs.main),
            path.join(this.options.rootDir, this.options.dirs.sub)
        ];

        chokidar
            .watch(watchPaths, {
                ignoreInitial: true,
                ignored: /(^|[\/\\])\../, // 忽略隐藏文件
                persistent: true
            })
            .on("all", async (event, filePath) => {
                console.log(chalk.blue(`检测到文件变化: ${filePath}`));
                await this.generate();
            });
    }
}

// 执行生成
const generator = new PagesGenerator();
generator.run();
